﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;

namespace CommHelper
{
    /// <summary>
    /// 枚举帮助类
    /// </summary>
    public sealed class EnumHelper
    {
        /// <summary>
        /// 获取枚举描述
        /// </summary>
        /// <param name="type"></param>
        /// <param name="enumName"></param>
        /// <returns></returns>
        public static string GetDescription(Type type, string enumName)
        {
            string description = string.Empty;
            foreach (FieldInfo info in type.GetFields())
            {
                if (!info.IsSpecialName && info.Name.Equals(enumName, StringComparison.CurrentCultureIgnoreCase))
                {
                    object[] customAttributes = info.GetCustomAttributes(typeof(DescriptionAttribute), false);
                    if (customAttributes.Length > 0)
                    {
                        description = ((DescriptionAttribute)customAttributes[0]).Description;
                    }
                }
            }
            if (description == string.Empty)
            {
                description = enumName;
            }
            return description;
        }
        /// <summary>
        /// 返回指定枚举类型的指定值的描述
        /// </summary>
        /// <param name="t">枚举类型</param>
        /// <param name="v">枚举值</param>
        /// <returns></returns>
        public static string GetDescription(Type t, object v)
        {
            try
            {
                FieldInfo oFieldInfo = t.GetField(GetName(t, v));
                var attributes =
                    (DescriptionAttribute[])oFieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
                return (attributes.Length > 0) ? attributes[0].Description : GetName(t, v);
            }
            catch
            {
                return string.Empty;
            }
        }

        private static string GetName(Type t, object v)
        {
            try
            {
                return Enum.GetName(t, v);
            }
            catch
            {
                return "UNKNOWN";
            }
        }
        /// <summary>
        /// 获取枚举描述
        /// </summary>
        /// <param name="enumName"></param>
        /// <returns></returns>
        public static string GetDescription<T>(string enumName)
        {
            Type type = typeof(T);
            return GetDescription(type, enumName);
        }

        /// <summary>
        /// 获取枚举描述
        /// </summary>
        /// <param name="enumObj"></param>
        /// <returns></returns>
        public static string GetDescription<T>(T enumObj)
        {
            Type type = typeof(T);
            return GetDescription(type, enumObj);
        }
        /// <summary>
        /// 获取枚举描述列表
        /// </summary>
        /// <returns></returns>
        public static string[] GetDescriptions<T>()
        {
            Type type = typeof(T);
            FieldInfo[] fields = type.GetFields();
            var list = new ArrayList();
            string description = string.Empty;
            foreach (FieldInfo info in fields)
            {
                if (!info.IsSpecialName)
                {
                    object[] customAttributes = info.GetCustomAttributes(typeof(DescriptionAttribute), false);
                    if (customAttributes.Length > 0)
                    {
                        description = ((DescriptionAttribute)customAttributes[0]).Description;
                        if (description == string.Empty)
                        {
                            description = customAttributes[0].ToString();
                        }
                        list.Add(description);
                    }
                }
            }
            var array = new string[list.Count];
            list.CopyTo(array);
            return array;
        }


        /// <summary>
        /// 通过枚举描述获取枚举项名称
        /// </summary>
        /// <param name="strDescription"></param>
        /// <returns></returns>
        public static string GetEnumNameByDescription<T>(string strDescription)
        {
            Type type = typeof(T);
            string[] arrDescription = GetDescriptions<T>();
            string sName = "";
            foreach (string str in Enum.GetNames(type))
            {
                if (GetDescription<T>(str) == strDescription)
                {
                    sName = str;
                    break;
                }
            }
            return sName;
        }

        /// <summary>
        /// 获取枚举索引列表
        /// </summary>
        /// <returns></returns>
        public static List<int> GetEnumObjectIndexList<T>()
        {
            var list = new List<int>();
            string[] names = Enum.GetNames(typeof(T));
            if ((names != null) && (names.Length > 0))
            {
                foreach (string str in names)
                {
                    var item = (int)Enum.Parse(typeof(T), str);
                    list.Add(item);
                }
            }
            return list;
        }

        /// <summary>
        /// 获取一个枚举类型的列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<T> GetEnumValueList<T>()
        {
            var list = new List<T>();
            var values = Enum.GetValues(typeof(T));
            if (values != null)
            {
                foreach (var tempValue in values.OfType<T>())
                    list.Add(tempValue);
            }
            return list;
        }

        /// <summary>
        /// 获取枚举成员索引
        /// </summary>
        /// <param name="type"></param>
        /// <param name="enumName"></param>
        /// <returns></returns>
        public static int GetEnumObjectIndex(Type type, string enumName)
        {
            int result = -1;
            string[] names = Enum.GetNames(type);
            if ((names != null) && (names.Length > 0))
            {
                foreach (string str in names)
                {
                    if (str != enumName)
                        continue;
                    result = (int)Enum.Parse(type, str);
                    break;
                }
            }
            return result;
        }

        /// <summary>
        /// 通过枚举字符串获取枚举类型
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="defaultType">默认枚举值</param>
        /// <param name="enumName">枚举字符串</param>
        /// <returns></returns>
        public static T GetEnumObject<T>(T defaultType, string enumName)
        {
            try
            {
                foreach (string str in Enum.GetNames(typeof(T)))
                {
                    if (!str.Equals(enumName + "", StringComparison.CurrentCultureIgnoreCase))
                        continue;
                    return (T)Enum.Parse(typeof(T), str, true);
                }
                return defaultType;
            }
            catch (Exception e)
            {
                throw new Exception("枚举转换异常：" + e.Message);
            }
        }

        /// <summary>
        /// 通过枚举字符串获取枚举类型
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="defaultType">默认枚举值</param>
        /// <param name="enumDesc">枚举字符串</param>
        /// <returns></returns>
        public static T GetEnumObjectByDesc<T>(T defaultType, string enumDesc)
        {
            T result = defaultType;
            string sName = GetEnumNameByDescription<T>(enumDesc);
            if (!string.IsNullOrEmpty(sName))
            {
                result = GetEnumObject<T>(defaultType, sName);
            }
            return result;
        }

        /// <summary>
        /// 通过枚举字符串获取枚举类型
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="defaultType">默认枚举值</param>
        /// <param name="enumValue">枚举字符串</param>
        /// <returns></returns>
        public static T GetEnumObject<T>(T defaultType, int enumValue)
        {
            try
            {
                if (Enum.IsDefined(typeof(T), enumValue))
                {
                    return (T)Enum.ToObject(typeof(T), enumValue);
                }
                return defaultType;
            }
            catch (Exception e)
            {
                throw new Exception("枚举转换异常：" + e.Message);
            }
        }

        /// <summary>
        /// 获取星期对应的中文名称
        /// </summary>
        /// <param name="strValue"></param>
        /// <returns></returns>
        public static string GetDayOfWeekEnumChiName(string strValue)
        {
            string ret = "";
            if (string.IsNullOrEmpty(strValue)) return ret;
            DayOfWeek v = GetEnumObject<DayOfWeek>(DayOfWeek.Sunday, strValue);
            switch (v)
            {
                case DayOfWeek.Friday:
                    ret = "星期五";
                    break;
                case DayOfWeek.Monday:
                    ret = "星期一";
                    break;
                case DayOfWeek.Saturday:
                    ret = "星期六";
                    break;
                case DayOfWeek.Sunday:
                    ret = "星期天";
                    break;
                case DayOfWeek.Thursday:
                    ret = "星期四";
                    break;
                case DayOfWeek.Tuesday:
                    ret = "星期二";
                    break;
                case DayOfWeek.Wednesday:
                    ret = "星期三";
                    break;
                default:
                    break;
            }
            return ret;
        }

        /// <summary>
        /// 获取星期对应的枚举数值
        /// </summary>
        /// <param name="strValue"></param>
        /// <returns></returns>
        public static string GetDayOfWeekEnumValue(string strValue)
        {
            string ret = "0";
            if (string.IsNullOrEmpty(strValue)) return ret;
            switch (strValue)
            {
                case "星期五":
                    ret = (int)DayOfWeek.Friday + "";
                    break;
                case "星期一":
                    ret = (int)DayOfWeek.Monday + "";
                    break;
                case "星期六":
                    ret = (int)DayOfWeek.Saturday + "";
                    break;
                case "星期日":
                    ret = (int)DayOfWeek.Sunday + "";
                    break;
                case "星期四":
                    ret = (int)DayOfWeek.Thursday + "";
                    break;
                case "星期二":
                    ret = (int)DayOfWeek.Tuesday + "";
                    break;
                case "星期三":
                    ret = (int)DayOfWeek.Wednesday + "";
                    break;
                default:
                    break;
            }
            return ret;
        }
    }
}
